package TestCases;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;

@SuppressWarnings("unused")
public class StartClient {
    static Logger log = LoggerUtils.getLogger(StartClient.class);

    static String filepath = ConfigUtil.getProperty("filepath", ConstantsUtil.CONFIG_COMMON);
    static String filename = ConfigUtil.getProperty("filename", ConstantsUtil.CONFIG_COMMON);
    static String max_file = ConfigUtil.getProperty("max_file", ConstantsUtil.CONFIG_COMMON);
    static int max_files = Integer.parseInt(ConfigUtil.getProperty("max_files", ConstantsUtil.CONFIG_COMMON));
    static int max_num = Integer.parseInt(ConfigUtil.getProperty("max_num", ConstantsUtil.CONFIG_COMMON));
    static String Interval_time = ConfigUtil.getProperty("Interval_time", ConstantsUtil.CONFIG_COMMON);
    static String happenTime = ConfigUtil.getProperty("happenTime", ConstantsUtil.CONFIG_COMMON);

    static int waitTime = Integer.parseInt(ConfigUtil.getProperty("waitTime", ConstantsUtil.CONFIG_COMMON));

    static long count = Long.valueOf(ConfigUtil.getProperty("count", ConstantsUtil.CONFIG_COMMON));
    static String type = ConfigUtil.getProperty("type", ConstantsUtil.CONFIG_COMMON);
    static String sqls = ConfigUtil.getProperty("sqls", ConstantsUtil.CONFIG_COMMON);
    static String sqls1 = ConfigUtil.getProperty("sqls1", ConstantsUtil.CONFIG_COMMON);

    // 从配置文件中读取数量
    static int n_srcIp = Integer.parseInt(ConfigUtil.getProperty("n_srcIp", ConstantsUtil.CONFIG_COMMON));
    static int n_destIp = Integer.parseInt(ConfigUtil.getProperty("n_destIp", ConstantsUtil.CONFIG_COMMON));
    static int n_visitTool = Integer.parseInt(ConfigUtil.getProperty("n_visitTool", ConstantsUtil.CONFIG_COMMON));
    static int n_operType = Integer.parseInt(ConfigUtil.getProperty("n_operType", ConstantsUtil.CONFIG_COMMON));
    static int n_dbUser = Integer.parseInt(ConfigUtil.getProperty("n_dbUser", ConstantsUtil.CONFIG_COMMON));
    static int n_ruleName = Integer.parseInt(ConfigUtil.getProperty("n_ruleName", ConstantsUtil.CONFIG_COMMON));
    static int riskLev_start = Integer.parseInt(ConfigUtil.getProperty("riskLev_start", ConstantsUtil.CONFIG_COMMON));
    static int riskLev_end = Integer.parseInt(ConfigUtil.getProperty("riskLev_end", ConstantsUtil.CONFIG_COMMON));
    static int Mac_num = Integer.parseInt(ConfigUtil.getProperty("Mac_num", ConstantsUtil.CONFIG_COMMON));
    static int ThreadsNums = Integer.parseInt(ConfigUtil.getProperty("threads_nums", ConstantsUtil.CONFIG_COMMON));

    static int CLICKHOUSE_BATCH_SIZE = Integer.parseInt(ConfigUtil.getProperty("ClickHouse.jdbc.batchSize", ConstantsUtil.CONFIG_JDBC));

    static String date = DateUtil.getDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS");


    private static Long COUNT = 0L;
    private static Long TOTAL_TIME = 0L;

    public static void main(String[] args) throws ParseException, InterruptedException, SQLException {

        switch (type) {
            // 随机
            case "random_lu":
                random_lu();
                // 比例
            case "scale_lu":
                scale_lu();
                // 随机
            case "random_ck":
                random_ck();
        }
    }

    public static void random_lu() throws InterruptedException {
        JSONObject Case = new JSONObject(true);
        BigInteger id = new BigInteger("165657378100470550");
        if (happenTime.isEmpty()) {
            happenTime = String.valueOf(DateUtil.getTime());
        }

        String srcMac = "00:0D:E9:08:37:D4";
        String systemUser = "";
        String systemHost = "";
        String destMac = "00:0D:E9:08:37:D5";
        String appAccount = "";
        String sessionId = "3788f2f3-482e-46fd-8cf3-8bcaa79408c9";
        String dbType = "3";
        String dbName = "";
        String tableName = "test_table0000000000";
        String fieldName = "所有字段";
        String sqlTemplateId = "7163112700047907533";
        String operSentence = "select * from test_table0000000000";
        List<String> operSentenceList = Arrays.asList(sqls1.split(";"));
        int operSentenceLen = 34;
        String sqlBindValue = "";
        int rowNum = 0;
        String sqlExecTime = "1.461000";
        int sqlResponse = 1;
        String returnContent = "";
        int returnContentLen = 0;
        int dealState = 0;
        String protectObjectName = "oracle_17.1.1.100";
        int ruleType = 0;
        String hwId = "4EB0219A85BEC937";
        String relatedInfo = "";
        int approvalStatus = 0;
        // 客户端ip
        String srcIp = "172.18.1.x";
        int srcPort = 37339;
        // 服务器ip
        String destIp = "172.19.1.x";
        int destPort = 1521;
        // 访问工具
        String visitTool = "jdbc.x";
        // 操作类型
        String operType = "select.x";
        // 数据库账户
        String dbUser = "test.x";
        // 规则名
        String ruleName = "sel.x";
        // 风险等级
//		int riskLev = 2;
        String tenantId = "0";
        String start_time = "";
        String end_time = "";
        try {

            BufferedOutputStream bos = null;
            int num = 1;
            int file_num = 1;
            int Case_Size = 1;
            int del_Size = 2;

            String filePath = "";
            if (filename.isEmpty()) {
                filePath = filepath + date + "_" + max_file + "/" + happenTime + "_" + max_num + ".fin";
            } else {
                filePath = filepath + filename + "/" + happenTime + "_" + max_num + ".fin";
            }
            log.info(filePath);
            bos = getbos(filePath);
            start_time = DateUtil.getDate();
            log.info("开始时间：" + start_time);
            long start = System.currentTimeMillis();
            for (int for_srcIp = 1; for_srcIp <= n_srcIp; for_srcIp++) {
                for (int for_destIp = 1; for_destIp <= n_destIp; for_destIp++) {
                    for (int for_visitTool = 1; for_visitTool <= n_visitTool; for_visitTool++) {
                        for (int for_operType = 1; for_operType <= n_operType; for_operType++) {
                            for (int for_dbUser = 1; for_dbUser <= n_dbUser; for_dbUser++) {
                                for (int for_ruleName = 1; for_ruleName <= n_ruleName; for_ruleName++) {
                                    for (int for_riskLev = riskLev_start; for_riskLev <= riskLev_end; for_riskLev++) {
                                        Case = new JSONObject(true);
//										Case.put("id", id);
                                        Case.put("id", new BigInteger(happenTime + for_riskLev + (1000 + 1 % 1000000)));
                                        Case.put("happenTime", Long.valueOf(happenTime.substring(0, happenTime.length() - 3)));
                                        Case.put("srcIp", srcIp.replace("x", String.valueOf(for_srcIp)));
                                        Case.put("srcPort", srcPort);
                                        Case.put("srcMac", srcMac);
                                        Case.put("systemUser", systemUser);
                                        Case.put("systemHost", systemHost);
                                        Case.put("destIp", destIp.replace("x", String.valueOf(for_destIp)));
                                        Case.put("destPort", destPort);
                                        Case.put("destMac", destMac);
                                        Case.put("visitTool", visitTool.replace("x", String.valueOf(for_visitTool)));
                                        Case.put("appAccount", appAccount);
                                        Case.put("sessionId", sessionId);
                                        Case.put("dbType", dbType);
                                        Case.put("dbUser", dbUser.replace(".x", String.valueOf(for_dbUser)));
                                        Case.put("operType", operType.replace("x", String.valueOf(for_operType)));
                                        Case.put("dbName", dbName);
                                        Case.put("tableName", tableName);
                                        Case.put("fieldName", fieldName);
                                        Case.put("sqlTemplateId", sqlTemplateId);
                                        Case.put("operSentence", RandomUtils.getRandomElement(operSentenceList));
                                        Case.put("operSentenceLen", operSentenceLen);
                                        Case.put("sqlBindValue", sqlBindValue);
                                        Case.put("rowNum", rowNum);
                                        Case.put("sqlExecTime", sqlExecTime);
                                        Case.put("sqlResponse", sqlResponse);
                                        Case.put("returnContent", returnContent);
                                        Case.put("returnContentLen", returnContentLen);
                                        Case.put("dealState", dealState);
                                        Case.put("protectObjectName", protectObjectName);
                                        Case.put("ruleType", ruleType);
                                        Case.put("ruleName", ruleName.replace("x", String.valueOf(for_ruleName)));
                                        Case.put("riskLev", for_riskLev);
                                        Case.put("hwId", hwId);
                                        Case.put("relatedInfo", relatedInfo);
                                        Case.put("approvalStatus", approvalStatus);
                                        Case.put("tenantId", tenantId);

                                        if (file_num > Integer.parseInt(max_file)) {
                                            bos.close();
                                            String date2 = DateUtil.getDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS");
                                            if (filename.isEmpty()) {
                                                filePath = filepath + date2 + "_" + max_file + "/" + happenTime + "_"
                                                        + max_num + ".fin";
                                            } else {
                                                filePath = filepath + filename + "/" + happenTime + "_" + max_num
                                                        + ".fin";
                                            }
//											log.info(filePath);
                                            bos = getbos(filePath);
                                            num = 1;
                                            file_num = 1;
                                            date = date2;
                                        }

                                        if (num > max_num) {
                                            bos.close();
//											String date1 = DateUtil.getDateFormat("yyyy_MM_dd_HH_mm_ss");
                                            if (filename.isEmpty()) {
                                                filePath = filepath + date + "_" + max_file + "/" + happenTime + "_"
                                                        + max_num + ".fin";
                                            } else {
                                                filePath = filepath + filename + "/" + happenTime + "_" + max_num
                                                        + ".fin";
                                            }
//											log.info(filePath);
                                            bos = getbos(filePath);
                                            num = 1;
//											Cases.clear();
                                        }

                                        bos.write(Case.toString().getBytes());
                                        bos.write("\r\n".getBytes());
//										log.info(Cases.size());
//										log.info(Case_Size);

                                        if (del_Size > max_files) {
                                            bos.close();
//											execShell("mv /data/luceneInfoDir/auditRecord1 /data/luceneInfoDir/auditRecord ");
                                            log.info("数据到达：" + max_files + " [" + numberToChinese(max_files) + "条数据]");
                                            File file1 = new File(filepath + filename);
                                            File file2 = new File(filepath + filename.replace("auditRecord1", "auditRecord"));
//											File file3 = new File(filepath + filename.replace("auditRecord", "auditRecord2"));
//											file2.renameTo(file3);
//											log.info("删除目录："+"【"+file2+"】");
//											deleteDir(file2);
//											log.info("修改目录：【"+file1+"】为"+"【"+file2+"】");
//											file1.renameTo(file2);

                                            // 原始文件路径
                                            log.info("移动文件：【" + filePath + "】为" + "【" + filePath.replace("auditRecord1", "auditRecord") + "】");
                                            Path sourcePath = Paths.get(filePath);
                                            // 目标文件路径（包括目标目录和新的文件名）
                                            Path destinationPath = Paths.get(filePath.replace("auditRecord1", "auditRecord"));
                                            // 使用NIO Files.move()方法，支持跨文件系统移动，并处理异常
                                            Files.move(
                                                    sourcePath,
                                                    destinationPath,
                                                    StandardCopyOption.REPLACE_EXISTING // 如果目标文件已存在则替换
                                            );

                                            filePath = filepath + filename + "/" + happenTime + "_" + max_num + ".fin";
                                            bos = getbos(filePath);
                                            del_Size = 1;
                                            log.info("等待：" + waitTime + "毫秒");
                                            Thread.sleep(waitTime);
                                        }

                                        num++;
                                        file_num++;
                                        Case_Size++;
                                        del_Size++;

                                        happenTime = String.valueOf((long) (Double.parseDouble(happenTime))
                                                + (long) (Double.parseDouble(Interval_time)));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            end_time = DateUtil.getDate();
            bos.close();
            long end = System.currentTimeMillis();
            long time = end - start;
            TOTAL_TIME += time;
            log.info("结束时间：" + end_time);
            log.info("总计耗时：" + formatTime(time));
            log.info("写入成功，总数：" + (Case_Size - 1));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void scale_lu() throws ParseException, InterruptedException {
        BigInteger id = new BigInteger("165657378100470550");
        if (happenTime.isEmpty()) {
            happenTime = String.valueOf(DateUtil.getTime());
        }
        // 客户端ip
//		String srcIp = "17.1.2.x";
        int srcPort = 37339;
        String srcMac = "00:0D:E9:08:37:D4";
        String systemUser = "";
        String systemHost = "";
        // 服务器ip
//		String destIp = "17.1.1.x";
        int destPort = 1521;
        String destMac = "00:0D:E9:08:37:D5";
        // 访问工具
        String visitTool = "jdbc.x";
        String appAccount = "";
        String sessionId = "3788f2f3-482e-46fd-8cf3-8bcaa79408c9";
        String dbType = "3";
        // 数据库账户
        String dbUser = "test.x";
        String dbName = "";
        String tableName = "test_table0000000000";
        String fieldName = "所有字段";
        String sqlTemplateId = "7163112700047907533";
        // 操作类型
//		String operType = "select.x";
        // 操作语句
//		String operSentence = "select * from test_table";
        int operSentenceLen = 34;
        String sqlBindValue = "";
        int rowNum = 0;
        String sqlExecTime = "1.461000";
        int sqlResponse = 1;
        String returnContent = "";
        int returnContentLen = 0;
        int dealState = 0;
        String protectObjectName = "oracle_17.1.1.100";
        int ruleType = 0;
        // 规则名
        String ruleName = "rule.x";
        // 风险等级
        String riskLev = "0";
        String hwId = "4EB0219A85BEC937";
        String relatedInfo = "";
        int approvalStatus = 0;
        String tenantId = "0";
        try {
            BufferedOutputStream bos = null;
            int num = 1;
            int file_num = 1;
            int Case_Size = 1;
            int del_Size = 2;
            int id_num = 1;

            String filePath = "";
            if (filename.isEmpty()) {
                filePath = filepath + date + "_" + max_file + "/" + happenTime + "_" + max_num + ".fin";
            } else {
                filePath = filepath + filename + "/" + happenTime + "_" + max_num + ".fin";
            }
            log.info("写入文件：" + filePath);
            bos = getbos(filePath);

            long start = System.currentTimeMillis();
            String start_time = DateUtil.getDate();
            log.info("开始时间：" + start_time);

//			List<JSONObject> list = getSqls();
            List<JSONObject> list = JSONObject.parseArray(sqls, JSONObject.class);
//			log.info(list);

            JSONArray Cases = new JSONArray();
            JSONObject Case = new JSONObject(true);

            JSONObject jsons = new JSONObject(true);
            JSONObject json = new JSONObject(true);

            Set<Integer> ip = new HashSet<>();
            for (int i = 1; i <= 255; i++) {
                ip.add(i);
            }

            Set<Integer> rule = new HashSet<>();
            for (int i = 1; i <= 2048; i++) {
                rule.add(i);
            }

            Set<Integer> port = new HashSet<>();
            for (int i = 1; i <= 65535; i++) {
                port.add(i);
            }

            Set<Integer> user = new HashSet<>();
            for (int i = 1; i <= 4096; i++) {
                user.add(i);
            }

//			String operType="";
            long operTypeNum = 0;
//			long count = 999999999;
            for (Long a = (long) 0; a < list.size(); a++) {
                json = new JSONObject(true);
                String scale = list.get(a.intValue()).getString("scale");
                Double scales = NumberFormat.getPercentInstance().parse(scale).doubleValue();
                operTypeNum = 0;
                String operType = list.get(a.intValue()).get("operType").toString();
                String operSentence = list.get(a.intValue()).get("operSentence").toString();
                String operSentence1 = operSentence;
                riskLev = list.get(a.intValue()).get("riskLev").toString();

                Long countLong = (long) (count * scales);
                int countInt = countLong.intValue();
//				log.info("【"+operType+"】"+"构造数据总量："+count);
//				log.info("【"+operType+"】"+"构造数据比例："+scales);
//				log.info("【"+operType+"】"+"数据风险等级："+riskLev);
//				log.info("【"+operType+"】"+"构造数据数量："+countInt);
                for (int b = 0; b < countInt; b++) {
                    operSentence = operSentence1.replace("纯数字", happenTime);
                    operSentence = operSentence.replace("字母加数字", UUID.randomUUID().toString());
                    operSentence = operSentence.replace("纯汉字", RandomUtils.createName());
                    Case = new JSONObject(true);
//					Case.put("id", id.add(new BigInteger(String.valueOf(b))));
                    Case.put("id", happenTime + riskLev + (1000 + b % 1000000));
//					Case.put("happenTime", happenTime);
                    Case.put("happenTime", Long.valueOf(happenTime.substring(0, happenTime.length() - 3)));
                    Case.put("srcIp", "172.19.1.1");
//					Case.put("srcIp", "172.19.1."+RandomUtils.getRandomElement(ip));
//					Case.put("srcPort", RandomUtils.getRandomElement(port));
                    Case.put("srcPort", srcPort);
//					Case.put("srcMac", RandomUtils.randomMacAddress());
                    Case.put("srcMac", srcMac);
//					Case.put("systemUser", "systemUser"+RandomUtils.getRandomElement(user));
                    Case.put("systemUser", systemUser);
                    Case.put("systemHost", systemHost);
                    Case.put("destIp", "172.19.1.2");
//					Case.put("destIp", "172.19.1."+RandomUtils.getRandomElement(ip));
//					Case.put("destPort", RandomUtils.getRandomElement(port));
//					Case.put("destMac", RandomUtils.randomMacAddress());
                    Case.put("destPort", destPort);
                    Case.put("destMac", destMac);
//					Case.put("visitTool", "jdbc"+RandomUtils.getRandomElement(ip));
                    Case.put("visitTool", "jdbc");
                    Case.put("appAccount", appAccount);
                    Case.put("sessionId", sessionId);
                    Case.put("dbType", dbType);
//					Case.put("dbUser", "dbUser"+RandomUtils.getRandomElement(user));
//					Case.put("dbName", "dbName"+RandomUtils.getRandomElement(user));
//					Case.put("tableName", "tableName"+RandomUtils.getRandomElement(user));
//					Case.put("fieldName", "fieldName"+RandomUtils.getRandomElement(user));
                    Case.put("dbUser", "dbUser");
                    Case.put("dbName", "dbName");
                    Case.put("tableName", "tableName");
                    Case.put("fieldName", "fieldName");
                    Case.put("operType", operType);
                    Case.put("sqlTemplateId", sqlTemplateId);
                    Case.put("operSentence", operSentence);
                    Case.put("operSentenceLen", operSentenceLen);
                    Case.put("sqlBindValue", sqlBindValue);
                    Case.put("rowNum", rowNum);
                    Case.put("sqlExecTime", sqlExecTime);
                    Case.put("sqlResponse", sqlResponse);
                    Case.put("returnContent", returnContent);
                    Case.put("returnContentLen", returnContentLen);
                    Case.put("dealState", dealState);
//					Case.put("protectObjectName", "172.19.2."+RandomUtils.getRandomElement(ip));
                    Case.put("protectObjectName", "172.19.2.1");
                    Case.put("ruleType", ruleType);
//					Case.put("ruleName", "rule"+RandomUtils.getRandomElement(rule));
                    Case.put("ruleName", "rule");
                    Case.put("riskLev", riskLev);
                    Case.put("hwId", hwId);
                    Case.put("relatedInfo", relatedInfo);
                    Case.put("approvalStatus", approvalStatus);
                    Case.put("tenantId", tenantId);
//				Cases.add(Case);

                    if (file_num > Integer.parseInt(max_file)) {
                        bos.close();
                        String date2 = DateUtil.getDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS");
                        if (filename.isEmpty()) {
                            filePath = filepath + date2 + "_" + max_file + "/" + happenTime + "_" + max_num + ".fin";
                        } else {
                            filePath = filepath + filename + "/" + happenTime + "_" + max_num + ".fin";
                        }
//						log.info(filePath);
                        bos = getbos(filePath);
                        num = 1;
                        file_num = 1;
                        date = date2;
                    }

                    if (num > max_num) {
                        bos.close();
//					String date1 = DateUtil.getDateFormat("yyyy_MM_dd_HH_mm_ss");
                        if (filename.isEmpty()) {
                            filePath = filepath + date + "_" + max_file + "/" + happenTime + "_" + max_num + ".fin";
                        } else {
                            filePath = filepath + filename + "/" + happenTime + "_" + max_num + ".fin";
                        }
//					    log.info(filePath);
                        bos = getbos(filePath);
                        num = 1;
//					    Cases.clear();
                    }

                    bos.write(Case.toString().getBytes());
                    bos.write("\r\n".getBytes());
//				log.info(Cases.size());
//				log.info(Case_Size);

                    if (del_Size > max_files) {
                        bos.close();
//						execShell("mv /data/luceneInfoDir/auditRecord1 /data/luceneInfoDir/auditRecord ");
                        log.info("数据到达：" + max_files + " [" + numberToChinese(max_files) + "条数据]");
//						File file1 = new File(filepath + filename);
//						File file2 = new File(filepath + filename.replace("auditRecord1", "auditRecord"));
//						File file3 = new File(filepath + filename.replace("auditRecord", "auditRecord2"));
////						file2.renameTo(file3);
//						log.info("删除目录："+"【"+file2+"】");
//						deleteDir(file2);
//						log.info("修改目录：【"+file1+"】为"+"【"+file2+"】");
//						file1.renameTo(file2);

                        // 原始文件路径
                        log.info("移动文件：【" + filePath + "】为" + "【" + filePath.replace("auditRecord1", "auditRecord") + "】");
                        Path sourcePath = Paths.get(filePath);
                        // 目标文件路径（包括目标目录和新的文件名）
                        Path destinationPath = Paths.get(filePath.replace("auditRecord1", "auditRecord"));
                        // 使用NIO Files.move()方法，支持跨文件系统移动，并处理异常
                        Files.move(
                                sourcePath,
                                destinationPath,
                                StandardCopyOption.REPLACE_EXISTING // 如果目标文件已存在则替换
                        );

                        filePath = filepath + filename + "/" + happenTime + "_" + max_num + ".fin";
                        bos = getbos(filePath);
                        del_Size = 1;
                        log.info("等待：" + waitTime + "毫秒");
                        Thread.sleep(waitTime);
                    }

                    num++;
                    file_num++;
                    Case_Size++;
                    del_Size++;
                    id_num++;
                    operTypeNum++;

                    happenTime = String.valueOf((long) (Double.parseDouble(happenTime)) + (long) (Double.parseDouble(Interval_time)));
//					BigDecimal  a1 = new BigDecimal(happenTime);
//					BigDecimal  a2 = new BigDecimal(Interval_time) ;
//					happenTime = a1.add(a2).toString();
                }

                id = id.add(new BigInteger(String.valueOf(id_num)));
//				log.info(""+operType+"："+operTypeNum);
                if (json.containsKey(operType)) {
                    operTypeNum = Long.valueOf(json.get(operType).toString()) + operTypeNum;
                }
                json.put("风险等级", riskLev);
                json.put("操作类型", operType);
                json.put("操作语句", operSentence);
                json.put("总计", count + " [" + numberToChinese(count) + "条数据]");
                json.put("占比", scale);
                json.put("数量", operTypeNum + " [" + numberToChinese(operTypeNum) + "条数据]");
                Cases.add(json);
            }
            bos.close();

            String end_time = DateUtil.getDate();
            long end = System.currentTimeMillis();
            long time = end - start;
            log.info("结束时间：" + end_time);
            log.info("总计耗时：" + formatTime(time));
            log.info("写入总数：" + (Case_Size - 1) + " [" + numberToChinese(Case_Size - 1) + "条数据]");
//			log.info(Cases);
            jsons.put("data", Cases);
            log.info(JsonFormatUtil.toPrettyFormat(jsons.toJSONString()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void random_ck() throws InterruptedException, SQLException {
        log.info("CK数据生成开始");
        List<String> Cases = new ArrayList<>();
        JSONObject Case = new JSONObject(true);
        // 任务开始时间
        long start = System.currentTimeMillis();
        BigInteger id = new BigInteger("165657378100470550");
        if (happenTime.isEmpty()) {
            happenTime = String.valueOf(DateUtil.getTime());
        }
        String tenantId = "0";
        // 随机生成多个Mac地址
        log.info("生成Mac地址：" + Mac_num + "个");
        String[] Mac = RandomUtils.generateMacAddresses(Mac_num);
        String systemUser = "";
        String systemHost = "";
        String appAccount = "";
        String sessionId = "3788f2f3-482e-46fd-8cf3-8bcaa79408c9";
        String dbType = "3";
        String dbName = "";
        String tableName = "test_table0000000000";
        String fieldName = "所有字段";
        String sqlTemplateId = "";
        // 操作语句
//        String operSentence = "select * from test_table0000000000";
        log.info("生成操作语句");
        List<String> operSentenceList = Arrays.asList(sqls1.split(";"));
        // 操作类型
        log.info("生成操作类型");
        List<String> operTypeList = SQLUtil.generateSQLType(operSentenceList);
        int operSentenceLen = 34;
        String sqlBindValue = "";
        int rowNum = 0;
        String sqlExecTime = "1.461000";
        int sqlResponse = 1;
        String returnContent = "";
        int returnContentLen = 0;
        int dealState = 0;
        String protectObjectName = "oracle_17.1.1.100";
        int ruleType = 0;
        String hwId = "4EB0219A85BEC937";
        String relatedInfo = "";
        int approvalStatus = 0;
        // 客户端ip
        log.info("生成客户端ip：100个");
        String[] srcIp = RandomUtils.generateIPAddresses(100);
        int srcPort = 37339;
        // 服务器ip
        log.info("生成服务器ip：100个");
        String[] destIp = RandomUtils.generateIPAddresses(100);
        int destPort = 1521;
        // 访问工具
        String visitTool = "jdbc.x";
        // 数据库账户
        String dbUser = "test.x";
        // 规则名
        String ruleName = "sel.x";
        // 风险等级
//		int riskLev = 2;

        // 创建一个随机数生成器，用于生成相应的数据库 操作类型和操作语句
        Random random = new Random();

        try {
            int caseSize = 1;
            for (int for_srcIp = 1; for_srcIp <= n_srcIp; for_srcIp++) {
                for (int for_destIp = 1; for_destIp <= n_destIp; for_destIp++) {
                    for (int for_visitTool = 1; for_visitTool <= n_visitTool; for_visitTool++) {
                        for (int for_dbUser = 1; for_dbUser <= n_dbUser; for_dbUser++) {
                            for (int for_ruleName = 1; for_ruleName <= n_ruleName; for_ruleName++) {
                                for (int for_riskLev = riskLev_start; for_riskLev <= riskLev_end; for_riskLev++) {
                                    log.info("开始生成第" + caseSize + "条数据");
                                    Case = new JSONObject(true);
                                    Case.put("id", new BigInteger(happenTime + for_riskLev + (1000 + 1 % 1000000)));
                                    Case.put("tenantId", tenantId);
                                    Case.put("happenTime", DateUtil.convertTimestampToLocalDateTime(Long.parseLong(happenTime), "yyyy-MM-dd HH:mm:ss"));
                                    Case.put("srcIp", RandomUtils.getRandomElement(srcIp));
                                    Case.put("srcPort", srcPort);
                                    Case.put("srcMac", RandomUtils.getRandomElement(Mac));
                                    Case.put("systemUser", systemUser);
                                    Case.put("systemHost", systemHost);
                                    Case.put("destIp", RandomUtils.getRandomElement(destIp));
                                    Case.put("destPort", destPort);
                                    Case.put("destMac", RandomUtils.getRandomElement(Mac));
                                    Case.put("visitTool", visitTool.replace("x", String.valueOf(for_visitTool)));
                                    Case.put("appAccount", appAccount);
                                    Case.put("sessionId", sessionId);
                                    Case.put("dbType", dbType);
                                    Case.put("dbUser", dbUser.replace(".x", String.valueOf(for_dbUser)));
                                    int index = random.nextInt(operSentenceList.size());
                                    Case.put("operType", operTypeList.get(index));
                                    Case.put("operSentence", operSentenceList.get(index));
                                    Case.put("dbName", dbName);
                                    Case.put("tableName", tableName);
                                    Case.put("fieldName", fieldName);
                                    Case.put("sqlTemplateId", sqlTemplateId);
                                    Case.put("operSentenceLen", operSentenceLen);
                                    Case.put("sqlBindValue", sqlBindValue);
                                    Case.put("rowNum", rowNum);
                                    Case.put("sqlExecTime", sqlExecTime);
                                    Case.put("sqlResponse", sqlResponse);
                                    Case.put("returnContent", returnContent);
                                    Case.put("returnContentLen", returnContentLen);
                                    Case.put("dealState", dealState);
                                    Case.put("protectObjectName", protectObjectName);
                                    Case.put("ruleType", ruleType);
                                    Case.put("ruleName", ruleName.replace("x", String.valueOf(for_ruleName)));
                                    Case.put("riskLev", for_riskLev);
                                    Case.put("hwId", hwId);
                                    Case.put("relatedInfo", relatedInfo);
                                    Case.put("approvalStatus", approvalStatus);
                                    Cases.add(Case.toJSONString());
                                    if (Cases.size() == CLICKHOUSE_BATCH_SIZE) {
                                        ClickHouseBatchInsertUtil.batchInsertJson3(for_riskLev, Cases, ThreadsNums);
                                        Cases = new ArrayList<>();
                                    }
                                    caseSize++;
                                    happenTime = String.valueOf((long) (Double.parseDouble(happenTime))
                                            + (long) (Double.parseDouble(Interval_time)));
                                }
                            }
                        }
                    }
                }
            }

            if (Cases.size() > 0) {
                log.info("当前存在已批量添加，未提交的数据：" + Cases.size() + "，开始批量提交已添加的数据！");
                ClickHouseBatchInsertUtil.batchInsertJson3(riskLev_start, Cases, ThreadsNums);
            }
            String end_time = DateUtil.getDate();
            long end = System.currentTimeMillis();
            long time = end - start;
            log.info("结束时间：" + end_time);
            log.info("总计耗时：" + formatTime(time));
            log.info("写入成功，总数：" + (caseSize - 1));
        } catch (
                Exception e) {
            e.printStackTrace();
        }

    }


    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir
                        (new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        if (dir.delete()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 运行shell脚本
     *
     * @param shell 需要运行的shell脚本
     */
    public static void execShell(String shell) {
        try {
            Runtime.getRuntime().exec(shell);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static List<JSONObject> getSqls() {
        JSONObject sql1 = getAuditRecord("drop", "DROP DATABASE TEST;", "4%");
        JSONObject sql2 = getAuditRecord("create", "CREATE DATABASE TEST;", "16%");
        JSONObject sql3 = getAuditRecord("show", "SHOW DATABASE;", "10%");
        JSONObject sql4 = getAuditRecord("use", "USE (TEST);", "10%");
        JSONObject sql5 = getAuditRecord("drop", "DROP TABLE `TEST`.`JDBC`;", "23%");
        JSONObject sql6 = getAuditRecord("create", "CREATE TABLE IF NOT EXISTS `TEST`.`JDBC`("
                + "   `id` INT UNSIGNED AUTO_INCREMENT,"
                + "   `name` VARCHAR(100) NOT NULL,"
                + "   `float` FLOAT NOT NULL,"
                + "   `long` LONGTEXT NOT NULL,"
                + "   `date` DATE,"
                + "   PRIMARY KEY ( `id` )"
                + ")ENGINE=InnoDB DEFAULT CHARSET=utf8;", "7%");
        JSONObject sql7 = getAuditRecord("insert", "INSERT INTO `TEST`.`JDBC` VALUES (1, '小王', 5/3,5/3,SYSDATE());", "1%");
        JSONObject sql8 = getAuditRecord("delete", "DELETE FROM `TEST`.`JDBC` WHERE id=2;", "2%");
        JSONObject sql9 = getAuditRecord("update", "UPDATE `TEST`.`JDBC` SET name='小李' WHERE id=1;", "16%");
        JSONObject sql10 = getAuditRecord("select", "SELECT * FROM `TEST`.`JDBC`;", "11%");

        List<JSONObject> list = new ArrayList<JSONObject>();
        list.add(sql1);
        list.add(sql2);
        list.add(sql3);
        list.add(sql4);
        list.add(sql5);
        list.add(sql6);
        list.add(sql7);
        list.add(sql8);
        list.add(sql9);
        list.add(sql10);
        return list;
    }

    public static JSONObject getAuditRecord(String operType, String operSentence, String scale) {
        Map<String, Object> auditRecordMap = new HashMap<>();
        auditRecordMap.put("operType", operType);
        auditRecordMap.put("operSentence", operSentence);
        auditRecordMap.put("scale", scale);
        JSONObject jsonObject = new JSONObject(auditRecordMap);
        return jsonObject;
    }

    public static void convert(int number) {
        // 数字对应的汉字
        String[] num = {"一", "二", "三", "四", "五", "六", "七", "八", "九"};
        // 单位
        String[] unit = {"", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千", "万亿"};
        // 将输入数字转换为字符串
        String result = String.valueOf(number);
        // 将该字符串分割为数组存放
        char[] ch = result.toCharArray();
        // 结果 字符串
        String str = "";
        int length = ch.length;
        for (int i = 0; i < length; i++) {
            int c = (int) ch[i] - 48;
            if (c != 0) {
                str += num[c - 1] + unit[length - i - 1];
            }
        }
        //System.out.println(str);
    }

    public static String numberToChinese(long number) {
        final String[] chineseNum = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        final String[] unit = {"", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千"};
        final String[] unit_type = {"", "万", "亿"};
        // 转数组
        char[] numberArray = (number + "").toCharArray();
        // 拼接成字符串
        StringBuilder dst = new StringBuilder("");
        // 循环 上次数字是否是 0
        boolean zero = false;
        // 单位级别
        int type = numberArray.length / 4;
        if (numberArray.length % 4 == 0) {
            // 刚好是级别切换
            type--;
        }
        for (int i = 0; i < numberArray.length; i++) {
            int num = (int) numberArray[i] - 48;
            // 判断是否到了级别切换
            if (i > 0 && (numberArray.length - i) % 4 == 0) {
                // 级别切换时，上次为 0，补齐单位名称
                if (zero) {
                    dst.append(unit_type[type]);
                }
                type--;
            }
            // 数字为0跳过
            if (num == 0) {
                zero = true;
                continue;
            }
            // 上次为0 且不是级别切换时，添加一个零,
            if (zero) {
                dst.append(chineseNum[0]);
            }
            // 数字
            dst.append(chineseNum[num]);
            // 单位
            if (i < numberArray.length - 1) {
                dst.append(unit[numberArray.length - i - 1]);
            }
            // 上次数字，设置为非 0
            zero = false;
        }
        return dst.toString();
    }

    public static String formatTime(Long ms) {
        Integer ss = 1000;
        Integer mi = ss * 60;
        Integer hh = mi * 60;
        Integer dd = hh * 24;

        Long day = ms / dd;
        Long hour = (ms - day * dd) / hh;
        Long minute = (ms - day * dd - hour * hh) / mi;
        Long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        StringBuffer sb = new StringBuffer();
        if (day > 0) {
            sb.append(day + "天");
        }
        if (hour > 0) {
            sb.append(hour + "小时");
        }
        if (minute > 0) {
            sb.append(minute + "分");
        }
        if (second > 0) {
            sb.append(second + "秒");
        }
        if (milliSecond > 0) {
            sb.append(milliSecond + "毫秒");
        }
        return sb.toString();
    }

    public static BufferedOutputStream getbos(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.getParentFile().exists()) { // 如果父目录不存在，创建父目录
            file.getParentFile().mkdirs();
        }
        if (file.exists()) { // 如果已存在,删除旧文件
            file.delete();
        }
        file = new File(filePath);
        file.createNewFile();

        OutputStream out = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(out);// 设置接受缓存
        return bos;
    }

    public static List<String> jsonArrayToList(JSONArray jsonArray) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            String value = jsonArray.getString(i);
            list.add(value);
        }
        return list;
    }
}
